package cn.ydxiaoshuai.modules.controller;

import cn.ydxiaoshuai.common.api.vo.api.AcnespotmoleBean;
import cn.ydxiaoshuai.common.api.vo.api.FaceMergeBean;
import cn.ydxiaoshuai.common.api.vo.api.TargetParam;
import cn.ydxiaoshuai.common.api.vo.api.TemplateParam;
import cn.ydxiaoshuai.common.constant.FaceConts;
import cn.ydxiaoshuai.common.factory.BDFactory;
import cn.ydxiaoshuai.common.sdkpro.AipFacePro;
import cn.ydxiaoshuai.common.system.base.controller.ApiRestController;
import cn.ydxiaoshuai.modules.conts.LogTypeConts;
import cn.ydxiaoshuai.modules.util.ApiBeanUtil;
import cn.ydxiaoshuai.modules.weixin.po.WXAccessToken;
import com.alibaba.fastjson.JSON;
import com.baidu.aip.util.Base64Util;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;


/**
 * @author 小帅丶
 * @className FaceMergeRestController
 * @Description 人脸融合、虚拟换妆
 * @Date 2020年5月29日14:30:57
 **/
@Controller
@RequestMapping(value = "/rest/face_merge")
@Scope("prototype")
@Slf4j
@Api(tags = "人脸融合、虚拟换妆-API")
public class FaceMergeRestController extends ApiRestController {

    AipFacePro aipFacePro = BDFactory.getAipFacePro();
    @Autowired
    private ApiBeanUtil apiBeanUtil;

    private static String APPID = "17362306";
    /**人脸融合*/
    private static String MERGE_URL_PREFIXX = "https://wximage-1251091977.cos.ap-beijing.myqcloud.com/facemergesml/";
    /**人脸变装*/
    private static String TRANSFER_DECORATION_URL_PREFIXX = "https://wximage-1251091977.cos.ap-beijing.myqcloud.com/facedecoration/";
    /**人脸美妆*/
    private static String TRANSFER_FACECOSMETIC_URL_PREFIXX = "https://wximage-1251091977.cos.ap-beijing.myqcloud.com/facecosmetic/";
    /**人脸滤镜*/
    private static String TRANSFER_PTUIMGFILTER_URL_PREFIXX = "https://wximage-1251091977.cos.ap-beijing.myqcloud.com/ptuimgfilter/";
    /**
     * @Description 虚拟换妆接口
     * @param source_image 目标图片文件
     * @param reference_images 模板图片文件
     * @return void
     * @Author 小帅丶
     * @Date 2020年7月15日
     **/
    @RequestMapping(value = "/diy/transfer", method = {RequestMethod.POST}, produces="application/json;charset=UTF-8")
    public ResponseEntity<Object> faceTransfer(@RequestParam(value = "source_image") MultipartFile source_image,
                                               @RequestParam(value = "reference_images") MultipartFile reference_images) {
        log.info("方法路径{}", requestURI);
        AcnespotmoleBean bean = new AcnespotmoleBean();
        AcnespotmoleBean.Data data = new AcnespotmoleBean.Data();
        JSONObject object = null;
        //人脸图片
        TargetParam sourceImage = new TargetParam();
        sourceImage.setImage_type(FaceConts.BASE64);
        //虚拟换妆模板图
        TemplateParam referenceImages = new TemplateParam();
        referenceImages.setImage_type(FaceConts.BASE64);
        try {
            startTime = System.currentTimeMillis();
            sourceImage.setImage(Base64Util.encode(source_image.getBytes()));
            referenceImages.setImage(Base64Util.encode(reference_images.getBytes()));
            param = "sourceImage="+JSON.toJSONString(sourceImage)+",referenceImages="+JSON.toJSONString(referenceImages);
            object = aipFacePro.faceTransfer(sourceImage, referenceImages,APPID);
            dealFaceMerge(object,bean,data,false);
        } catch (Exception e) {
            errorMsg = e.getMessage();
            log.info("虚拟换妆接口出错了" + errorMsg);
            bean.error("system error", "系统错误");
        }
        //耗时
        timeConsuming = String.valueOf(System.currentTimeMillis() - startTime);
        log.info("虚拟换妆接口耗时{}",timeConsuming);
        beanStr = JSON.toJSONString(bean);
        apiBeanUtil.putLog(bean.getLog_id(), timeConsuming, beanStr, ip, param, requestURI, errorMsg, LogTypeConts.FACE_TRANSFER_DIY,userId,userAgent);
        //响应的内容
        return new ResponseEntity<Object>(beanStr, httpHeaders, HttpStatus.OK);
    }
    /**
     * @Description 虚拟换妆接口
     * @param file 图片文件
     * @return void
     * @Author 小帅丶
     * @Date 2020年7月15日
     **/
    @RequestMapping(value = "/transfer", method = {RequestMethod.POST}, produces="application/json;charset=UTF-8")
    public ResponseEntity<Object> Transfer(@RequestParam(value = "file") MultipartFile file) {
        log.info("方法路径{}", requestURI);
        AcnespotmoleBean bean = new AcnespotmoleBean();
        JSONObject object = null;
        //模板图片地址
        String templateURL = "";
        //风格  1变妆  2美妆
        String style = ServletRequestUtils.getStringParameter(request, "style","1");
        //模板ID
        String templateId = ServletRequestUtils.getStringParameter(request, "templateId","1");
        if(style.equals("1")){
            templateURL  = TRANSFER_DECORATION_URL_PREFIXX+templateId+".jpg";
        }else if(style.equals("2")){
            templateURL  = TRANSFER_FACECOSMETIC_URL_PREFIXX+templateId+".png";
        }else{
            if(templateId.equals("10")||templateId.equals("11")||templateId.equals("29")
            ||templateId.equals("7")||templateId.equals("8")||templateId.equals("9")){
                templateURL  = TRANSFER_PTUIMGFILTER_URL_PREFIXX+templateId+".gif";
            }else{
                templateURL  = TRANSFER_PTUIMGFILTER_URL_PREFIXX+templateId+".png";
            }
        }
        //模板图
        TemplateParam referenceImages = new TemplateParam();
        referenceImages.setImage_type(FaceConts.URL);
        referenceImages.setImage(templateURL);
        //人脸图片
        TargetParam sourceImage = new TargetParam();
        sourceImage.setImage_type(FaceConts.BASE64);
        try {
            startTime = System.currentTimeMillis();
            AcnespotmoleBean.Data data = new AcnespotmoleBean.Data();
            sourceImage.setImage(Base64Util.encode(file.getBytes()));
            param = "sourceImage="+JSON.toJSONString(sourceImage)+",referenceImages="+JSON.toJSONString(referenceImages);
            object = aipFacePro.faceTransfer(sourceImage, referenceImages,APPID);
            if(LogTypeConts.API_VERSION.equals(version)){
                WXAccessToken imgCheckBean = apiBeanUtil.checkImg(request, file);
                if(imgCheckBean.getErrcode()==0){
                    dealFaceMerge(object,bean,data,false);
                }else{
                    bean.fail("img fail", imgCheckBean.getErrmsg(),imgCheckBean.getErrcode());
                }
            }else{
                dealFaceMerge(object,bean,data,false);
            }
        } catch (Exception e) {
            errorMsg = e.getMessage();
            log.info("虚拟换妆接口出错了" + errorMsg);
            bean.error("system error", "系统错误");
        }
        //耗时
        timeConsuming = String.valueOf(System.currentTimeMillis() - startTime);
        log.info("虚拟换妆接口耗时{}",timeConsuming);
        beanStr = JSON.toJSONString(bean);
        apiBeanUtil.putLog(bean.getLog_id(), timeConsuming, beanStr, ip, param, requestURI, errorMsg, LogTypeConts.FACE_TRANSFER,userId,userAgent);
        //响应的内容
        return new ResponseEntity<Object>(JSON.toJSONString(bean), httpHeaders, HttpStatus.OK);
    }
    /**
     * @Description 人脸融合接口
     * @param target_file 目前图片文件
     * @param template_file 模板图片文件
     * @return void
     * @Author 小帅丶
     * @Date 2020年5月29日14:30:57
     **/
    @RequestMapping(value = "/diy/merge", method = {RequestMethod.POST}, produces="application/json;charset=UTF-8")
    public ResponseEntity<Object> faceMerge(@RequestParam(value = "target_file") MultipartFile target_file,
                                            @RequestParam(value = "template_file") MultipartFile template_file) {
        log.info("方法路径{}", requestURI);
        AcnespotmoleBean bean = new AcnespotmoleBean();
        AcnespotmoleBean.Data data = new AcnespotmoleBean.Data();
        JSONObject object = null;
        //模板图
        TemplateParam template = new TemplateParam();
        template.setImage_type(FaceConts.BASE64);
        //人脸图片
        TargetParam target = new TargetParam();
        target.setImage_type(FaceConts.BASE64);
        try {
            startTime = System.currentTimeMillis();
            template.setImage(Base64Util.encode(template_file.getBytes()));
            target.setImage(Base64Util.encode(target_file.getBytes()));
            param = "sourceImage="+JSON.toJSONString(template)+",referenceImages="+JSON.toJSONString(target);
            object = aipFacePro.faceMerge(template, target);
            dealFaceMerge(object,bean,data,true);
        } catch (Exception e) {
            errorMsg = e.getMessage();
            log.info("痘斑痣检测接口出错了" + errorMsg);
            bean.error("system error", "系统错误");
        }
        //耗时
        timeConsuming = String.valueOf(System.currentTimeMillis() - startTime);
        log.info("人脸融合接口耗时{}",timeConsuming);
        beanStr = JSON.toJSONString(bean);
        apiBeanUtil.putLog(bean.getLog_id(), timeConsuming, beanStr, ip, param, requestURI, errorMsg, LogTypeConts.FACE_MERGE_DIY,userId,userAgent);
        //响应的内容
        return new ResponseEntity<Object>(JSON.toJSONString(bean), httpHeaders, HttpStatus.OK);
    }


    /**
     * @Description 人脸融合接口
     * @param file 图片文件
     * @return void
     * @Author 小帅丶
     * @Date 2020年5月29日14:30:57
     **/
    @RequestMapping(value = "/merge", method = {RequestMethod.POST}, produces="application/json;charset=UTF-8")
    public ResponseEntity<Object> faceMerge(@RequestParam(value = "file") MultipartFile file) {
        log.info("方法路径{}", requestURI);
        AcnespotmoleBean bean = new AcnespotmoleBean();
        AcnespotmoleBean.Data data = new AcnespotmoleBean.Data();
        JSONObject object = null;
        //模板ID
        String templateId = ServletRequestUtils.getStringParameter(request, "templateId","1");
        //模板图片地址
        String templateURL = MERGE_URL_PREFIXX+templateId+"l.png";
        //模板图
        TemplateParam template = new TemplateParam();
        template.setImage_type(FaceConts.URL);
        template.setImage(templateURL);
        //人脸图片
        TargetParam target = new TargetParam();
        try {
            startTime = System.currentTimeMillis();
            target.setImage(Base64Util.encode(file.getBytes()));
            target.setImage_type(FaceConts.BASE64);
            object = aipFacePro.faceMerge(template, target);
            param = "sourceImage="+JSON.toJSONString(template)+",referenceImages="+JSON.toJSONString(target);
            if(LogTypeConts.API_VERSION.equals(version)){
                WXAccessToken imgCheckBean = apiBeanUtil.checkImg(request, file);
                if(imgCheckBean.getErrcode()==0){
                    dealFaceMerge(object,bean,data,true);
                }else{
                    bean.fail("img fail", imgCheckBean.getErrmsg(),imgCheckBean.getErrcode());
                }
            }else{
                dealFaceMerge(object,bean,data,true);
            }
        } catch (Exception e) {
            errorMsg = e.getMessage();
            log.info("人脸融合接口出错了" + errorMsg);
            bean.error("system error", "系统错误");
        }
        //耗时
        timeConsuming = String.valueOf(System.currentTimeMillis() - startTime);
        log.info("人脸融合接口耗时{}",timeConsuming);
        beanStr = JSON.toJSONString(bean);
        apiBeanUtil.putLog(bean.getLog_id(), timeConsuming, beanStr, ip, param, requestURI, errorMsg, LogTypeConts.FACE_MERGE,userId,userAgent);
        //响应的内容
        return new ResponseEntity<Object>(JSON.toJSONString(bean), httpHeaders, HttpStatus.OK);
    }
    /**
     * @Author 小帅丶
     * @Description 处理数据
     * @Date  2020/5/29 16:15
     * @param object 接口返回的对象
     * @param bean 响应回去的对象
     * @param data 具体内容
     * @param isMerge 是否为人脸融合
     * @return void
     **/
    private void dealFaceMerge(JSONObject object,AcnespotmoleBean bean, AcnespotmoleBean.Data data,boolean isMerge) {
        FaceMergeBean faceMergeBean = JSON.parseObject(object.toString(),FaceMergeBean.class);
        if (faceMergeBean.getError_code()==0) {
            if(isMerge){
                data.setImage_base64(faceMergeBean.getResult().getMerge_image());
                bean.success("success", "融合成功",data);
            }else {
                data.setImage_base64(faceMergeBean.getResult().getTransfer_image());
                bean.success("success", "虚拟换妆融合成功",data);
            }
        } else {
            bean.fail("fail", faceMergeBean.getError_msg(), faceMergeBean.getError_code());
        }
    }
}
